package com.yl.chainStore.common.handler

import com.yl.chainStore.common.enums.Status
import com.yl.chainStore.common.enums.CustomerShowEnum
import com.yl.chainStore.common.enums.TypeEnum
import com.yl.chainStore.payrule.coupons.CouponsRuleTypeEnum
import com.yl.chainStore.payrule.item.ItemRuleTypeEnum
import com.yl.chainStore.payrule.order.OrderRuleTypeEnum
import com.yl.common.Flag
import com.yl.common.UserType
import com.yl.users.common.enum.CustomerCertificateType
import com.yl.users.common.enum.CustomerSourceType
import com.yl.users.common.enum.CustomerType
import com.yl.users.common.enum.UserPackageTypeEnum
import org.apache.ibatis.type.EnumTypeHandler
import org.apache.ibatis.type.JdbcType
import java.sql.*
import kotlin.jvm.Throws

/**
 *
 * create by 2021/6/16.
 * @author udbjqr
 */
class YLEnumTypeHandler<E : Enum<E>>(val type: Class<E>? = null) : EnumTypeHandler<E>(type) {

    override fun getResult(cs: CallableStatement?, columnIndex: Int): E {
        return super.getResult(cs, columnIndex)
    }

    override fun getResult(rs: ResultSet?, columnIndex: Int): E {
        return super.getResult(rs, columnIndex)
    }

    override fun getResult(rs: ResultSet?, columnName: String?): E {
        return super.getResult(rs, columnName)
    }

    override fun setParameter(ps: PreparedStatement?, i: Int, parameter: E, jdbcType: JdbcType?) {
        super.setParameter(ps, i, parameter, jdbcType)
    }

    @Throws(SQLException::class)
    override fun setNonNullParameter(ps: PreparedStatement, i: Int, parameter: E, jdbcType: JdbcType?) {
        when (type) {
            TypeEnum::class.java -> {
                ps.setInt(i, (parameter as TypeEnum).code)
                return
            }
            Status::class.java -> {
                ps.setInt(i, (parameter as Status).code)
                return
            }
            Flag::class.java -> {
                ps.setInt(i, (parameter as Flag).value)
                return
            }
            UserType::class.java -> {
                ps.setInt(i, (parameter as UserType).value)
                return
            }
            CustomerType::class.java -> {
                ps.setInt(i, (parameter as CustomerType).code)
                return
            }
            CustomerCertificateType::class.java -> {
                ps.setInt(i, (parameter as CustomerCertificateType).code)
                return
            }
            CustomerSourceType::class.java -> {
                ps.setInt(i, (parameter as CustomerSourceType).code)
                return
            }
            UserPackageTypeEnum::class.java -> {
                ps.setInt(i, (parameter as UserPackageTypeEnum).code)
                return
            }
            CouponsRuleTypeEnum::class.java -> {
                ps.setInt(i, (parameter as CouponsRuleTypeEnum).code)
                return
            }
            ItemRuleTypeEnum::class.java -> {
                ps.setInt(i, (parameter as ItemRuleTypeEnum).code)
                return
            }
            OrderRuleTypeEnum::class.java -> {
                ps.setInt(i, (parameter as OrderRuleTypeEnum).code)
                return
            }
            CustomerShowEnum::class.java -> {
                ps.setInt(i, (parameter as CustomerShowEnum).code)
                return
            }
            else -> {
                if (jdbcType == null) {
                    ps.setString(i, parameter.name)
                } else {
                    ps.setObject(i, parameter.name, jdbcType.TYPE_CODE)
                }
            }
        }


    }

    @Throws(SQLException::class)
    override fun getNullableResult(rs: ResultSet, columnName: String?): E? {
        val s = rs.getString(columnName)

        return when (type) {
            TypeEnum::class.java -> {
                TypeEnum.getEnum(rs.getInt(columnName)) as E
            }
            Status::class.java -> {
                Status.getEnum(rs.getInt(columnName)) as E
            }
            Flag::class.java -> {
                Flag.getEnum(rs.getInt(columnName)) as E
            }
            UserType::class.java -> {
                UserType.getEnum(rs.getInt(columnName)) as E
            }
            CustomerType::class.java -> {
                CustomerType.getEnum(rs.getInt(columnName)) as E
            }
            CustomerSourceType::class.java -> {
                CustomerSourceType.getEnum(rs.getInt(columnName)) as E
            }
            CustomerCertificateType::class.java -> {
                CustomerCertificateType.getEnum(rs.getInt(columnName)) as E
            }
            UserPackageTypeEnum::class.java -> {
                UserPackageTypeEnum.getEnum(rs.getInt(columnName)) as E
            }
            CouponsRuleTypeEnum::class.java -> {
                CouponsRuleTypeEnum.getEnum(rs.getInt(columnName)) as E
            }
            ItemRuleTypeEnum::class.java -> {
                ItemRuleTypeEnum.getEnum(rs.getInt(columnName)) as E
            }
            OrderRuleTypeEnum::class.java -> {
                OrderRuleTypeEnum.getEnum(rs.getInt(columnName)) as E
            }
            CustomerShowEnum::class.java -> {
                CustomerShowEnum.getEnum(rs.getInt(columnName)) as E
            }
            else -> {
                if (s == null) null else java.lang.Enum.valueOf(type, s)
            }
        }
    }

    @Throws(SQLException::class)
    override fun getNullableResult(rs: ResultSet, columnIndex: Int): E? {
        val s = rs.getString(columnIndex)
        return if (s == null) null else java.lang.Enum.valueOf(type, s)
    }

    @Throws(SQLException::class)
    override fun getNullableResult(cs: CallableStatement, columnIndex: Int): E? {
        val s = cs.getString(columnIndex)
        return if (s == null) null else java.lang.Enum.valueOf(type, s)
    }
}
